package net.lookyou.boot.demo.config.security.filter;

import com.alibaba.fastjson.JSONObject;
import net.lookyou.boot.demo.config.security.token.PhoneAuthenticationToken;
import net.lookyou.boot.demo.entity.SysUser;
import net.lookyou.boot.demo.exception.CustomerAuthenticationException;
import net.lookyou.boot.demo.mapper.UserMapper;
import net.lookyou.boot.demo.utils.MultiReadHttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * 手机号码自定义登录拦截器
 */
public class PhoneAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    
    @Resource
    private UserMapper userMapper;

    /**
     * 微信code
     */
    private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/phone-login", "POST");

    private boolean postOnly = true;
    private static final String METHOD_POST = "POST";

    public PhoneAuthenticationFilter() {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
    }

    public PhoneAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(DEFAULT_ANT_PATH_REQUEST_MATCHER, authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException {
        if (this.postOnly && !METHOD_POST.equals(request.getMethod())) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }

        MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request);
        // 将前端传递的数据转换成jsonBean数据格式
        SysUser requestUser = JSONObject.parseObject(wrappedRequest.getBodyJsonStrByJson(wrappedRequest), SysUser.class);
        if (StringUtils.isBlank(requestUser.getPhone())) {
            throw new AuthenticationServiceException("手机号码不能为空");
        }

        if (StringUtils.isBlank(requestUser.getCode())) {
            throw new AuthenticationServiceException("验证码不能为空");
        }

        String sessionCode = (String) request.getSession().getAttribute("code");
        System.out.println("session中验证码：" + sessionCode + "  用户上送code:" + requestUser.getCode());
        if (!requestUser.getCode().equalsIgnoreCase(sessionCode)) {
            throw new CustomerAuthenticationException(500, "验证码错误");
        }

        SysUser user = userMapper.selectOne(new SysUser() {{
            setPhone(requestUser.getPhone());
        }});

        if (Objects.isNull(user)) {
            throw new AuthenticationServiceException("用户不存在");
        }


        PhoneAuthenticationToken authRequest = new PhoneAuthenticationToken(requestUser.getPhone());
        this.setDetails(request, authRequest);
        return this.getAuthenticationManager().authenticate(authRequest);

    }


    protected void setDetails(HttpServletRequest request, PhoneAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }

    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }


}
